home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Documentation / Engineering Notes / Views / Using Controls < prev    next >
Encoding:
Text File  |  1996-08-16  |  25.1 KB  |  432 lines  |  [TEXT/ttxt]

  1. OpenDoc
  2. Development
  3. Framework
  4.  
  5.                                                                                                                                                                                            
  6. Using Controls 
  7. ODF Release 1                                                                                                                                                                     
  8.  
  9.  
  10. Table of Contents
  11. -------------------------
  12. • Abstract
  13. • Using ODF Controls
  14.     • Adding Controls to Your Frame
  15.     • Using Notifications
  16.     • FW_CNativeControl Interface
  17. • Using Buttons (FW_CButton)
  18.     • Creation by Program or Resource
  19.     • Button view Attributes
  20.     • Button Kinds
  21.     • Button Values
  22.     • Button Messages
  23.     • Radio Clusters
  24. • Using Popup menu (FW_CPopupMenu)
  25.     • Creation by Program or Resource
  26.     • Control Attributes
  27.     • Popup Menu Attributes
  28.     • Adding and Removing Menu Items
  29.     • Reading Popup Menu Items
  30.     • Using Popup Menu Notifications
  31. • Using Scroll bars (FW_CScrollBar)
  32.     • Creation by Program or Resource
  33.     • Using Scroll Bars in Scrollers
  34. • Miscellaneous issues
  35.     • Adding Colors to Controls
  36.  
  37. Abstract
  38.  
  39. This document explains how to work with the view objects derived from the class FW_CControl.  It supersedes the section "Adding Controls to your view" starting on page 93 of the ODF Developer's Guide shipped with ODF Release 1.   This release supports the basic Macintosh controls, buttons, scroll bars and popup menus.  The architecture is in place to add more custom controls in the future and to use the same API to support controls on other platforms.  ODF Form is our show-case example for controls, you should read this with the Form project open, ready to browse its source code.
  40.  
  41. Note on Controls and OpenDoc
  42.  
  43. Using native Macintosh controls in OpenDoc parts is one area when ODF does a lot of extra work for you, since displaying controls properly in a "non-application world" can be quite challenging.  However, we did leave some problems to be solved in future releases, especially with respect to controls that are displayed across multiple facets. 
  44.  
  45.  
  46. Using ODF Controls
  47.  
  48. The class hierarchy for  ODF 1 control classes is the following:
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63. Controls are small UI objects that respond to user interactions and send notifications to let your part know when to perform appropriate actions. A control derives from FW_CView, it's a lightweight view which cannot contain any subviews. It also inherits from FW__MNotifier in order to send notifications to other objects.  
  64.  
  65. This release implements only the standard controls, i.e. platform native controls.  They belong to their own FW_CNativeControl class because they are wrappers to underlying Mac OS controls.  A future ODF release will support native controls for other platforms.  We will also implement custom controls which don't have an underlying platform equivalent, such as Icon buttons on the Macintosh.
  66.  
  67. FW_CRadioCluster is not a control class per se but is used in conjunction with radio buttons to manage a group of mutually exclusive buttons.
  68.  
  69. Adding Controls to Your Frame
  70.  
  71. When you create a control, you must specify a superview object to be the parentView of the control.  The superview can be the frame itself.  ODF stores the control in the parent's subviews list and redraws it along with any other subviews.  
  72.  
  73. FW_CControl::FW_CControl(Environment* ev, 
  74.                                      FW_CSuperView* parentView,
  75.                                      ODID viewId,
  76.                                      const FW_CRect& bounds,
  77.                                      FW_Message msg,
  78.                                      FW_ControlValue value) 
  79.  
  80. • viewId can be 0 or a number to identify this view within the parent view (it only needs to be unique within the parent's view hierarchy).
  81. • bounds specify the position and size of the control within the parent view.
  82. • msg is what is sent when the control's value changes, or 0 if you are not interested in this event.
  83. • value is the initial value of this control, for instance 1 for a radio button or check-box.
  84.  
  85. The easiest way to add controls is to define them in resources in the list of your frame's views.  You must use a resource type from a derived class because FW_CControl and FW_CNativeControl are abstract classes.  For instance the resource definition of a  button looks like this:
  86.  
  87.              FW_RButton
  88.              (
  89.                           kSubscribeButtonID,                                                  // view id
  90.                           {FW_FIX(300),FW_FIX(750),FW_FIX(450),FW_FIX(775)},    // view bounds
  91.                           FW_kFixedBounds,                                                        // view binding
  92.                           FW_kButtonPressedMsg,                                          // control message
  93.                           FW_kFrameReceiver,                                                   // control receiver
  94.                           0,                                                                            // control value
  95.                           FW_kPushButton,                                                         // button kind
  96.                           FW_SYSTEM_FONT,                                                         // button font
  97.                           "Join ODFWired!"                                                        // button label
  98.                 )
  99.  
  100. The same button can be created by program with the following code:
  101.  
  102.                 FW_CString label("Join ODFWired!");
  103.                 viewRect.Set(FW_IntToFixed(300),FW_IntToFixed(750),FW_IntToFixed(450),FW_IntToFixed(775));
  104.                 FW_CButton* pushButton = FW_NEW(FW_CButton, (ev, this, kSubscribeButtonID, 
  105.                                                                                                                                                                                                 viewRect, FW_kPushButton, label));
  106.                 pushButton->LinkControlTo(ev, frame);
  107.  
  108. Control resource types are declared in the file ODF:Framewrk:FWViews:Include:FWViews.fr.  See also the file ODF:Framewrk:FWViews:Include:FWViews.k for common constants.
  109.  
  110. Using Notifications
  111.  
  112. Because controls are also FW_MNotifier objects they can broadcast messages to other objects when the user interacts with them, usually with a mouse click.  For each control you must decide which FW_MReceiver object(s) will be interested in receiving the control's message.  The Engineering note "Notification" gives a general description of the notification subsystem and its classes.  We will limit this section to what is specific to controls.
  113.  
  114. In general a control has only 1 receiver, its parent view or the frame itself.  The receiver is a custom class, in which you implement a HandleNotification method to respond to this control and maybe others.  The easiest way to connect a control to its receiver is by using the constant FW_kViewReceiver or FW_kFrameReceiver in the control resource definition as shown above with the button example.  Leave 0 in that field for controls which don't need receivers.  If you create the control without using resources, or if you need to define more than 1 receiver, you can use the method LinkControlTo which takes a receiver argument.
  115.  
  116. Both the receiver resource field and the LinkControlTo method have the effect of creating a FW_CInterest object with the control's message and adding it to the receiver's list of interests, i.e. the following code is executed internally:
  117.  
  118.                 receiver->AddInterest(FW_CInterest(this, GetMessage(ev)));
  119.  
  120. The control's message value is the  data sent when the control's value changes: this happens either when it is clicked on or when its value is modified by program with SetValue().  ODF controls use the following  constants defined in FWNotDef.h:
  121.  
  122.                     // Values which can be used in your view resources
  123.                     const FW_Message    FW_kNullMsg            = 0;
  124.                     const FW_Message    FW_kButtonPressedMsg    = -10;                    // standard msg for buttons
  125.                     const FW_Message    FW_kDefaultButtonMsg    = -12;                    // reserved for dialogs
  126.                     const FW_Message    FW_kCancelButtonMsg    = -13;                     // reserved for dialogs
  127.                     const FW_Message    FW_kPopupClickedMsg    = -20;                     // standard msg for popups 
  128.  
  129.                     // Values which cannot be used directly in your view resources
  130.                     const FW_Message    FW_kScrollMsg        = -100;    
  131.                     const FW_Message    FW_kRadioClusterMsg    = -101;
  132.                     const FW_Message    FW_kNotifierDeletedMsg    = -102;    
  133.  
  134. In general you are interested in responding to buttons and popup menu selections.  You can use the predefined constants FW_kButtonPressedMsg and FW_kPopupClickedMsg or you can define your own message values (use positive numbers to avoid future conflicts with ODF).  
  135.  
  136. The last step is to implement the HandleNotification method in your receiver class.  The following listing shows how a class derived from FW_CFrame and FW_MReceiver responds to buttons:
  137.  
  138.                 void  MyFrameClass::HandleNotification(Environment* ev, 
  139.                                          const FW_CNotification& notification)
  140.                 {
  141.                                 switch(notification.GetMessage())
  142.                                 {
  143.                                                 case FW_kButtonPressedMsg:
  144.                               // Safe cast to FW_CControlNotification
  145.                               FW_CControlNotification* controlNotification =
  146.                                                                                                                                                                             (FW_CControlNotification*)notification;
  147.  
  148.                               // Now we can get the control or the view id
  149.                               FW_CControl* control = controlNotification.GetControl(ev);
  150.                               ODID viewId = controlNotification.GetViewId(ev);
  151.                                  ...
  152.                                  break;
  153.                           ...
  154.  
  155. All controls send messages of the type FW_CControlNotification, which carries more information than the base type FW_CNotification.  You can safely cast the notification argument and retrieve a pointer to the control itself or its view id.  Popup menus and scroll bars can  use their own types FW_CPopupMenuNotification  and FW_CScrollNotification.
  156.  
  157. FW_CNativeControl Interface
  158.  
  159. FW_CNativeControl adds the following methods to its base class FW_CControl:
  160.  
  161. Disable(), Enabled()
  162.  
  163. Use Disable to gray out a button and Enable to make it active again.  Controls are always enabled by default.  If you want a button to be disabled when the frame is created you must call Disable it in your frame's PostCreateViewFromStream method since this attribute is not available in the resource type.
  164.  
  165. SetLabel(), GetLabel() 
  166.  
  167. These methods allow you to change or read a button's or popup's label.  The last parameter of SetLabel should be false only if you are sure that the control doesn't need to be refreshed right away.
  168.  
  169. GetPlatformControlHandle() 
  170.  
  171. This method returns a handle to the native platform control, you can cast it to ControlHandle on the Macintosh.  This may be convenient to retrieve more information about a control however it is not generally possible to change any internal attribute this way without confusing ODF.
  172.  
  173. Other new methods of FW_CNativeControl don't need to be called directly from your part's code.
  174.  
  175.  
  176. Using Buttons (FW_CButton)
  177.  
  178. Creation by Program or Resource
  179.  
  180. The class FW_CButton implements the native buttons, push button, radio button and check box.  Use the resource type FW_RButton to define a button in resources as shown earlier, or use the class constructor:
  181.  
  182.                 FW_CButton(Environment* ev, 
  183.                          FW_CSuperView* container, 
  184.                          ODID viewId,
  185.                          const FW_CRect& bounds,
  186.                          FW_ButtonKind kind,
  187.                          const FW_CString& label,
  188.                          const FW_CFont& font = FW_kSystemFont12,
  189.                          FW_Message msg = FW_kButtonPressedMsg,
  190.                          FW_ControlValue value = 0);
  191.  
  192.  
  193. Button view Attributes
  194.  
  195. You need to define a view id that is unique within the parent view, unless you are not interested in using this view id later to access the button object or handle the button's notifications.
  196.  
  197. The view binding attribute is initialized to FW_kFixedBounds in order to keep buttons in a fixed position when their parent view is resized.  You can change that by calling FW_CView::SetBindings or by using a different initial value in the button resource.  Binding constants are defined in ODF:Framewrk:FWViews:Include:FWViews.k
  198.  
  199. Button Kinds
  200.  
  201. The possible values for the "kind" argument are: FW_kPushButton, FW_kRadioButton, FW_kCheckButton and FW_kDefaultPushButton.  This last kind should be used to create a push button with the standard Macintosh outline indicating that it responds to <Return> and <Enter> keys (you must also use the FW_kDefaultButtonMsg message value at the same time).
  202.  
  203. GetButtonKind() returns the kind value.
  204.  
  205. SetButtonKind() can be used to change from FW_kPushButton to FW_kDefaultPushButton, or vice-versa, at runtime.
  206.  
  207. Button Values
  208.  
  209. Radio buttons and check boxes can have a control value of 0 or 1 to indicate their state.  Use a value of 1 in the button constructor or the button resource to turn the button on.  The states of push buttons don't change, their value is always 0.  
  210.  
  211. The methods GetState and SetState are equivalent to FW_CControl methods GetValue and SetValue except that they use boolean arguments.
  212.  
  213. Changing the value of a radio button or check box makes the button broadcast a notification containing the button's message (unless this message is 0).
  214.  
  215. Button Messages
  216.  
  217. In order to respond to a mouse click in a push button you must set its message field to a non-null value, either the predefined constant FW_kButtonPressedMsg or your own value.  
  218.  
  219. The default and cancel buttons of a dialog frame should use the constants FW_kDefaultButtonMsg and FW_kCancelButtonMsg respectively.  This makes them respond to certain keys  (<Return> or <Enter> for the default button, Command-<period> or <Escape> for the cancel button) as if they were clicked in.   In addition, this allows the base class FW_CDialogFrame to dismiss the dialog.
  220.  
  221. In general you won't need to respond to mouse clicks in radio buttons and check boxes, only the state of these controls is of interest.  You should leave the message field set to 0 and also leave the resource's control receiver field null.
  222.  
  223. Radio Clusters
  224.  
  225. A group of radio buttons represents a set of mutually exclusive choices.  Only one button at a time should be turned on and clicking on another button should turn off the previous selected button.  This behavior can be easily implemented by creating an FW_CRadioCluster object for each group of radio buttons.
  226.  
  227. In resources, use the type FW_RRadioCluster after the list of subviews where the radio buttons are declared.  Follow the example of ODF Form (ODF:Form:Sources:Views.fr), right now you need to include the radio cluster(s) in your own superview resource type because of a resource compiler bug:
  228.  
  229.     FW_RRadioCluster    
  230.     (
  231.             1,                                                                       // Dummy field
  232.             { k14400RadioID, k28800RadioID, kFasterRadioID } // List of radio buttons
  233.     ),
  234.  
  235. You can also create the radio cluster by program like this:
  236.  
  237.     fRadioCluster = FW_NEW(FW_CRadioCluster, (ev));
  238.     fRadioCluster->AddRadio(ev, radio1);
  239.     fRadioCluster->AddRadio(ev, radio2);
  240.     fRadioCluster->AddRadio(ev, radio3);
  241.  
  242. The selected (or "on") button is either the first one added to the cluster or the last one which was created with a value of 1.  In general it's easier to list the buttons in the same order as they appear visually and initialize one of them with a value of 1.
  243.  
  244. Radio cluster objects don't need to be deleted in your frame's destructor.  They are deleted automatically when the last button is removed during the destruction of views (this a case where FW_kNotifierDeletedMsg is used).
  245.  
  246. FW_CRadioCluster::GetButtonOn() returns the currently selected button,  FW_CRadioCluster::GetButtonIdOn() returns its view id.
  247.  
  248. Note: A radio cluster object is not a view, it is purely a receiver which turns buttons on and off.  If you need to demarcate a group of radio buttons with a border and a label add a FW_CGroupBox view before the buttons, as it is done in Form.
  249.  
  250.  
  251. Using Popup Menus (FW_CPopupMenu)
  252.  
  253. Creation by Program or Resource
  254.  
  255. The class FW_CPopupMenu implements native popup menus.   To create a popup menu you can either use a resource FW_RPopupMenu or the constructor of FW_CPopupMenu.  In the current release you must also create a Mac MENU resource with ResEdit or another tool and add it to your part editor project (in a future release we will support the same ODF menu resources used for the menu bar).  See ODF Form for an example using popup menus.
  256.  
  257.     FW_RPopupMenu
  258.     (
  259.               kOnlineTimePopupID,                        // view id
  260.               { FW_FIX(30),FW_FIX(540),FW_FIX(230),FW_FIX(560)},
  261.               FW_kFixedBounds,                              // binding
  262.               0,                                                  // control message
  263.               0,                                                  // control receiver
  264.               0,                                                  // control value
  265.               kOnlineTimeMenuResID,                      // Mac menu id
  266.               0,                                                  // title width
  267.               1,                                                  // Initial menu item
  268.               0,                                                  // Menu variation
  269.               0,                                                  // Menu refCon    
  270.               FW_SYSTEM_FONT,                               // Menu font
  271.               ""                                                  // title
  272.        ),
  273.  
  274. Control Attributes
  275.  
  276. The control value is not used, leave it set to 0.  The message and receiver attributes should be left null as well if you are not interested in responding to popup selections, otherwise use the constant FW_kPopupClickedMsg or your own custom message and set the receiver field to the frame or the parent view.
  277.  
  278. Popup Menu Attributes
  279.  
  280. This release uses the native Macintosh popup menus and thus relies on the same attributes (see chapter 5 of Inside Macintosh:Macintosh ToolBox Essentials for more information):
  281.  
  282. • The Mac menu id is the MENU resource built separately with ResEdit or another tool.  If you forget to add this resource to your part there won't be any error at the creation of the popup but it will be invisible.
  283.  
  284. • The title width is the pixel width of the title (do not use fixed coordinates like elsewhere!).  You can leave 0 even if you specify a title, in which case the width will be adjusted automatically.
  285.  
  286. • The initial menu item lets you specify which menu item should be visible first.
  287.  
  288. • The menu variation can be one of the popup variants defined in the Mac header <controls.h>.  In particular you can use popupUseAddResMenu to fill a popup with a list of resources of a certain type, for instance a list of Fonts.
  289.  
  290. • The menu refCon field can be used in conjunction with a variation of popupUseAddResMenu to specify the resource type, for instance the long value equal to 'FONT'.
  291.  
  292. • The menu font should be FW_SYSTEM_FONT by default.
  293.  
  294. • The menu title is not required.
  295.  
  296. Other Mac popup menu attributes can be accessed or modified by using the call GetPlatformControlHandle.
  297.  
  298. Adding and Removing Menu Items
  299.  
  300. There is no direct API yet to add or remove menu items but you can do it with Mac toolbox calls after accessing the native menu handle with GetPlatformMenuHandle().  If you need to create the popup menu from scratch for instance you can start with  a MENU resource containing only 1 item and delete it.
  301.  
  302.     #ifdef FW_BUILD_MAC
  303.        FW_CPopupMenu* popup = (FW_CPopupMenu*)FindViewById(ev, kBrowseTimePopupID);
  304.        MenuHandle macMenu = (MenuHandle)popup->GetPlatformMenuHandle();
  305.        AppendMenu(macMenu, "\pMy new item");   // use a pascal string
  306.     #endif
  307.  
  308. Reading Popup Menu Items
  309.  
  310. GetMenuString(Environment* ev, FW_CString& str)  reads the current menu item in str.
  311.  
  312. GetMenuString(Environment* ev, short index, FW_CString& str) reads the menu item at position index (starting with 1)
  313.  
  314. Using Popup Menu Notifications
  315.  
  316. To perform an action in response to a menu item selection you  need to do two things:
  317.  
  318. 1) Set your control message and control receiver fields in the popup resource definition.
  319.  
  320.     FW_RPopupMenu
  321.     (
  322.            ...
  323.         FW_kPopupClickedMsg,          // default popup message (or your own)
  324.         FW_kFrameReceiver,            // frame is receiver (or FW_kViewReceiver)
  325.               ...
  326.  
  327. If the popup menu is created by program the message is already set by the class constructor.  You must connect the popup menu to its receiver with a line like this:
  328.  
  329.         popup1->LinkControlTo(ev, frame);
  330.  
  331. 2) Implement the HandleNotification method in your frame or your view and trap the FW_kPopupClickedMsg message.  The notification received is an instance of FW_CPopupMenuNotification.  It provides two additional APIs over its base class FW_CControlNotification: GetMenuString and GetMenuIndex.
  332.  
  333.     void  CFormFrame::HandleNotification(Environment* ev, 
  334.                                     const FW_CNotification& notification)
  335.     {
  336.               switch(notification.GetMessage())
  337.               {
  338.                     case FW_kPopupClickedMsg: 
  339.                     {
  340.                             const FW_CPopupMenuNotification& popupNotification = 
  341.                                                             (FW_CPopupMenuNotification&) notification;
  342.                 
  343.                             // No need to check the view id, this frame has only 1 popup menu
  344.                             // We retrieve the menu item selected
  345.                             FW_CString itemString;
  346.                             popupNotification.GetMenuString(ev, itemString);
  347.                             ...
  348.                     }    
  349.                     break;
  350.  
  351. Remember that reselecting the current menu item doesn't trigger any notification (the control's value stays the same).
  352.  
  353.  
  354. Using Scroll Bars (FW_CScrollBar)
  355.  
  356. Creation by Program or Resource
  357.  
  358. The class FW_CScrollBar implements native scroll bar controls.   To create one you can either use a resource FW_RScrollBar or the constructor of FW_CScrollBar. 
  359.  
  360. The class constructor takes very few arguments.  When creating it by program you only need to define its bounds; you can leave the view id as 0 because it won't be used elsewhere:
  361.  
  362.         FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, 0, vertSbRect));
  363.  
  364. The bounds rectangle vertSbRect determines if it's a vertical or horizontal scroll bar.  Its width, or height, must be 16 pixels on the Macintosh to get the correct look.   We recommend to use the following call to read the default size and not hard-code any platform specific value:
  365.  
  366.         FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  367.  
  368. The resource type contains more fields than the class constructor but you will usually leave default values in all them except the first two:
  369.  
  370.        FW_RScrollBar        // Vertical
  371.        (
  372.                kVertScrollBarID,                               // view id
  373.                {H - FW_SBSIZE, -FW_ONE, H1, V1 - FW_SBSIZE},    // bounds 
  374.                FW_kVScrollBarBinding,                       // Standard vertical SB binding
  375.                0,                                                             // control message 
  376.                0,                                                             // control receiver 
  377.                0,                                                             // control value
  378.                0,                                                             // SB Min Value (adjusted at runtime)
  379.                1,                                                             // SB Max Value (adjusted at runtime)
  380.                FW_ONE,                                                     // Minor Units (adjusted at runtime)
  381.                FW_ONE                                                      // Major Units (adjusted at runtime)
  382.       ),
  383.  
  384. • A unique view id is required when the scroll bar is used in a scroll bar scroller, it will be repeated in the FW_RScrollBarScroller resource.
  385.  
  386. • The bounds can take advantage of the macro FW_SBSIZE.  Remember also to overlap the edge of the scroll bar by one pixel with its parent view to avoid creating a thicker line.
  387.  
  388. • The view binding should be either FW_kVScrollBarBinding or FW_kHScrollBarBinding, to make the scroll bar follow the edge of its parent view when resizing occurs.
  389.  
  390. • The message and receiver fields should stay 0 unless you want the scroll bar to notify other objects when its value changes.   This is separate from the FW_kScrollMsg notification that is always sent internally when the scroll bar is clicked on.  The scroller object is not declared in the scroll bar receiver field, it is the other way around.
  391.  
  392. • The last four fields, min, max, minor units and major units, are not used for regular scroll bars associated with a scroller because the scroller adjusts these scroll bar parameters at runtime.  You only need to enter valid values if the scroll bar is connected to another kind of object which won't adjust its parameters.
  393.  
  394. Using Scroll Bars in Scrollers
  395.  
  396. See the Engineering note "Scrolling" in the same folder.  This covers also FW_CScrollNotification.
  397.  
  398.  
  399. Miscellaneous Issues
  400.  
  401. Adding Colors to Controls
  402.  
  403. Macintosh controls use a white background color by default (or rather the background color of their window's grafport).   Check boxes and radio buttons will come out as white rectangles over a non-white parent view.   In order to make them look "transparent" you can create a color table either for the frame's window or for each control individually.  Adding a background color at the window level is enough if all controls can share the same background color.  If two or more colors are required you need to modify the controls themselves (do it in the PostCreateViewFromStream method, use GetPlatformControlHandle to access the Mac handle and use toolbox calls to create the color table). 
  404.  
  405. Form provides an example of adding a color table to a dialog window:
  406.  
  407. #ifdef FW_BUILD_MAC
  408.  
  409.     void CPwdDialogFrame::FacetAdded(Environment* ev, ODFacet* facet, 
  410.                                          unsigned short facetCount)
  411.     {
  412.             FW_CDialogFrame::FacetAdded(ev, facet, facetCount);
  413.     
  414.             if (facetCount == 1)
  415.             {
  416.                     ODPlatformWindow platformWindow = 
  417.                                  facet->GetWindow(ev)->GetPlatformWindow(ev);
  418.         
  419.                     WCTabHandle newColorTable = (WCTabHandle)
  420.                                   FW_CMemoryManager::AllocateSystemHandle(8+sizeof(ColorSpec));
  421.                     (*newColorTable)->ctSize = 0;
  422.                     (*newColorTable)->ctTable[0].value = wContentColor;
  423.                     (*newColorTable)->ctTable[0].rgb = FW_CColor(FW_kRGBLightGray);
  424.                     ::SetWinColor(platformWindow, newColorTable);
  425.             }
  426.     }
  427.  
  428. #endif
  429.  
  430.  
  431. © 1993 - 1996 Apple Computer, Inc. All rights reserved.
  432. Apple, the Apple Logo, Macintosh, and OpenDoc are trademarks of Apple Computer, Inc., registered in the United States and other countries.